
/* 
* @author huanglinlong
* @date 2018年9月7日 上午9:36:55 
* Copyright  ©2018 网金社
*/

package com.junitUtil.baseTest;

import org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory;
import org.springframework.test.util.ReflectionTestUtils;

import com.junitUtil.spring.BeanCreatUtils;
import com.junitUtil.util.AopTargetUtils;

//import static org.springframework.context.weaving.AspectJWeavingEnabler.ASPECTJ_AOP_XML_RESOURCE;

import java.lang.reflect.Field;
import org.mockito.Mockito;

/**
 * 注意！！！ 不要在测试类中使用@ Autowired 来注入bean，否则会导致aop失效
 * 程序在运行时通过aop自动加载需要用到的属性
 * aop逻辑：
 *      系统将对com.wjs或com.hundsun.wjs包下的所有文件按 MyAspect 此类下的配置进行aop处理
 *      切面MyAspect 会对com.wjs或com.hundsun.wjs包下的各类的有 Autowired 注解的属性进行 aop处理
 *      aop处理是如果该属性为空，则创建一个bean并返回
 * 使用方法
 *  1.给测试类增加jvm参数或者全局增加jvm参数 -javaagent:org.springframework.instrumentjar(需要该jar包的完整路径)
 *  2.可选 ：通过@ AopTarget 来调整aop的逻辑
 *  3.看需求配置数据库，3中配置方法
 *      2.1使用注解@TestDbConfig 指定
 *      2.2 通过@BeforeClass 注解的方法 调用setQuick方法  
           @BeforeClass
            public static  void before() throws Exception{
                setQuick(  "classpath:jtester.properties" );// 按需加载
            }
 *      2.3 不做任何配置 系统默认读取项目下的"config.properties"或者 "server.properties"，可能读取错误 
 *  4.通过 getBean 方法获取bean，mock方法进行mock 处理
 *  示例：
    public class  FundTest extends   AspectBaseServiceTest{
     @Test
     public void b() throws Exception{
           StageTaskService stageTaskService=getBean(StageTaskService.class);
           WithdrawCurrentsLogic withdrawCurrentsLogic=mock(WithdrawCurrentsLogic.class, stageTaskService);
           stageTaskService.queryWithdrawSuccessRate();
     }
    }
 * @author huanglinlong
 * @date 2018年9月7日 上午9:36:55
 * 
 **/
public class AspectBaseServiceTest extends AbstractBaseTest {
    
    public <T> T getBean(Class<T> cls) throws Exception {
        AbstractAutowireCapableBeanFactory beanFactory = (AbstractAutowireCapableBeanFactory) context.getAutowireCapableBeanFactory();
        T t = BeanCreatUtils.getBean(cls, beanFactory, true);
        return t;
    }
    
    
    
    public <T> T mock(Class<T> mockCls, Object target) throws Exception {
        T t = Mockito.mock(mockCls);
       AbstractAutowireCapableBeanFactory beanFactory = (AbstractAutowireCapableBeanFactory) context.getAutowireCapableBeanFactory();
       beanFactory.registerSingleton(mockCls.getName(), t);
        for(Field field:AopTargetUtils.getTarget(target).getClass().getDeclaredFields()){
            if(field.getType().isAssignableFrom(mockCls)){
                ReflectionTestUtils.setField(AopTargetUtils.getTarget(target),field.getName(),t );
            }
        }
         return t;
    }

//    @SuppressWarnings("rawtypes")
//    @Before
//    public void init() throws Exception {
//        context.getBean(AnnotationAwareAspectJAutoProxyCreator.class).setExposeProxy(true);
//        AbstractAutowireCapableBeanFactory beanFactory = (AbstractAutowireCapableBeanFactory) context.getAutowireCapableBeanFactory();
//        for (Field field : this.getClass().getDeclaredFields()) {
//            field.setAccessible(true);
//            if (field.getAnnotation(Autowired.class) != null) {
//                Object obj = BeanCreatUtils.getBean(field.getType(), beanFactory, true);
//                field.set(this, obj);
//            }
//        }
//
//        AopTargetUtils.mock(this);
//
//    }

}
